package com.ahora.org.controller.MBean;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpSession;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.SelectEvent;

import com.ahora.org.controller.util.ListaGeneral;
import com.ahora.org.ejb.dao.util.Util;
import com.ahora.org.ejb.dao.util.Validaciones;
import com.ahora.org.ejb.facade.interfaces.DocumentoInternoFacade;
import com.ahora.org.ejb.jpa.beans.AreaDTO;
import com.ahora.org.ejb.jpa.beans.BandejaDTO;
import com.ahora.org.ejb.jpa.beans.DocumentoInternoDTO;
import com.ahora.org.ejb.jpa.beans.GenericoBean;
import com.ahora.org.ejb.jpa.beans.RequisitoProcesosDTO;
import com.ahora.org.ejb.jpa.entities.Accion;
import com.ahora.org.ejb.jpa.entities.Area;
import com.ahora.org.ejb.jpa.entities.DocumentoUsuario;
import com.ahora.org.ejb.jpa.entities.EstadoGenerales;
import com.ahora.org.ejb.jpa.entities.TipoDocumentosInternos;
import com.ahora.org.ejb.jpa.entities.Usuario;

@SessionScoped
@ManagedBean(name = "documentosBM")
public class DocumentosBM {

	@EJB
	private DocumentoInternoFacade serDocInt;
	private List<GenericoBean> listconCopia;
	private GenericoBean conCopia;
	private String value = "";
	private Usuario userLog;
	private int idComboTipDocInt;
	private int codDocum = 0;
	private ExternalContext ect = null;
	private HttpSession session = null;
	private String textCC = "";
	private String codDocumentoString;
	private ArrayList<byte[]> arrbytes = null;
	private String text = "";
	private List<Usuario> listUsers;
	private int codExpediente = -1;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getTextCC() {
		return textCC;
	}

	public void setTextCC(String textCC) {
		this.textCC = textCC;
	}

	public List<GenericoBean> getListconCopia() {
		return listconCopia;
	}

	public void setListconCopia(List<GenericoBean> listconCopia) {
		this.listconCopia = listconCopia;
	}

	public GenericoBean getConCopia() {
		return conCopia;
	}

	public void setConCopia(GenericoBean conCopia) {
		this.conCopia = conCopia;
	}

	public int getCodDocum() {
		return codDocum;
	}

	public void setCodDocum(int codDocum) {
		this.codDocum = codDocum;
	}

	public String getCodDocumentoString() {
		return codDocumentoString;
	}

	public void setCodDocumentoString(String codDocumentoString) {
		this.codDocumentoString = codDocumentoString;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public Usuario getUserLog() {
		userLog = (Usuario) session.getAttribute("usuarioLogin");
		return userLog;
	}

	public void setUserLog(Usuario userLog) {
		this.userLog = userLog;
	}

	public int getIdComboTipDocInt() {
		return idComboTipDocInt;
	}

	public void setIdComboTipDocInt(int idComboTipDocInt) {
		this.idComboTipDocInt = idComboTipDocInt;
	}

	public ArrayList<byte[]> getArrbytes() {
		return arrbytes;
	}

	public void setArrbytes(ArrayList<byte[]> arrbytes) {
		this.arrbytes = arrbytes;
	}

	public List<SelectItem> getListadoDocumentosInternos() {
		ArrayList<SelectItem> listTipoExp = new ArrayList<SelectItem>();
		try {
			for (TipoDocumentosInternos c : lstDocumentosInternos) {
				listTipoExp.add(new SelectItem(c.getIdTipoDocumentoInternos(),
						c.getDescripcion()));
			}
		} catch (Exception e) {
			e.getMessage();
		}

		return listTipoExp;
	}

	public DocumentosBM() {
		ect = FacesContext.getCurrentInstance().getExternalContext();
		session = (HttpSession) ect.getSession(true);

		listconCopia = new ArrayList<GenericoBean>();
		conCopia = new GenericoBean();
		listDocInt = new ArrayList<DocumentoInternoDTO>();
		// ListaGeneral.actualizarListaDocumentosInternosUsuario(); =====>>>
		// TIENES QUE VER EN DONDE LO VAS A COLOCAR
	}

	public List<Usuario> getListUsers() {

		return listUsers;
	}

	public void setListUsers(List<Usuario> listUsers) {
		this.listUsers = listUsers;
	}

	public int getCodExpediente() {
		try {
			codExpediente = (Integer) session.getAttribute("idExpediente");
		} catch (Exception e) {
			codExpediente = -1;
		}

		return codExpediente;
	}

	public void setCodExpediente(int codExpediente) {
		this.codExpediente = codExpediente;
	}

	// Adjuntar los usuarios a CON COPIA

	public void cambioSeleccionDocumento(ActionEvent a) {
		try {
			if (this.idComboTipDocInt == -1) {
				Util.mensajeCompletoInfo("",
						"Debe seleccionar un tipo de documento");
				docInter.setCodigo("");
				return;

			} else {
				docInter.setIdTipoDocumento(this.idComboTipDocInt);
				docInter.setCodigo(serDocInt.obtenerCodigoTipoDocumento(docInter));
				for (TipoDocumentosInternos td : lstDocumentosInternos) {
					if (this.idComboTipDocInt == td
							.getIdTipoDocumentoInternos()) {
						docInter.setNombreTipoDocumento(td.getDescripcion().trim());
						break;
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String enviarDocumentoUsuario() {
		String link = "";
		String mensaje = "";
		try {
			if (lstUsuariosDistino.size()<1) {
				mensaje = "Ingrese minimo un usario de destino correcto";
				return "crearDocumento";
			}
			if (this.idComboTipDocInt == -1) {
				mensaje = "Seleccione un tipo de documento";
				return "crearDocumento";
			}
			
				DocumentoUsuario objDU = new DocumentoUsuario();
				TipoDocumentosInternos objTDI = new TipoDocumentosInternos();
				// TbUsuario objURemitente = new TbUsuario();
				EstadoGenerales objEstGen = new EstadoGenerales();

				// tbTipoDocumentosInternos; //ID_TIPO_DOCUMENTO_INTERNOS
				objTDI.setIdTipoDocumentoInternos(this.idComboTipDocInt);
				objDU.setTbTipoDocumentosInternos(objTDI);

				// private String observacion; OBSERVACION // El contenido del
				// documento
				objDU.setObservacion(Validaciones.stringToByte(this.value));

				// tbEstadoGenerales; ID_ESTADO_D_R_E
				objEstGen.setIdEstadoDRE(10);
				objDU.setTbEstadoGenerale(objEstGen);
				// El estado por default
				objDU.setIdEstado(1);

				if (getCodExpediente() > 0) {
					setCodExpediente(-1);
				}
				
				
				
				mensaje = serDocInt.enviarDocumentoInterno(
						this.idComboTipDocInt, objDU, getUserLog(), lstUsuariosDistino,
						lstUsuariosCopia, getCodExpediente(), docInter);
				listDocInt = listaDocumentosInternosUsuario(getUserLog());
				ExternalContext context = FacesContext.getCurrentInstance()
						.getExternalContext();
				HttpSession session = (HttpSession) context.getSession(true);
				session.setAttribute("listDocInt", listDocInt);
				link = "expedientes";
				limpiar();
				
			FacesContext ct = FacesContext.getCurrentInstance();
			ct.addMessage(null, new FacesMessage("", mensaje));

		} catch (Exception e) {
			link = "crearDocumento";
			e.printStackTrace();
		}
		return link;
	}

	private void limpiar() {
		setText("");
		setTextCC("");
		setCodDocumentoString("");
		setIdComboTipDocInt(0);
		setValue("");
		listconCopia.clear();
		conCopia = new GenericoBean();
		listDocInt = new ArrayList<DocumentoInternoDTO>();
		docSelected = new DocumentoInternoDTO();
		docSelected.setFechaRegistro(Validaciones.getTimeStampFromServer());
	}

	String realPath = "";

	public List<String> usurioDestino(String query) {
		List<String> results = new ArrayList<String>();
		try {
			for (Usuario u : listUsers) {
				if (u.getIdUsuario() != getUserLog().getIdUsuario()) {
					String areaUsu = u.getTbArea().getDescripcion().trim();
					String nomComp = u.getNombres().trim() + " "
							+ u.getApellPater().trim() + " "
							+ u.getApellMater().trim();
					if (compararCadenas(areaUsu, query.trim()) == true
							|| compararCadenas(nomComp, query.trim())) {
						String desc = areaUsu + " - " + nomComp;
						results.add(desc);
					}
				}
			}
			if (results.size() < 1) {
				results.add("No se encuentran resultados");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return results;
	}

	public List<String> usuarioCopia(String query) {
		List<String> results = new ArrayList<String>();
		try {
			for (Usuario u : listUsers) {
				if (u.getIdUsuario() != getUserLog().getIdUsuario()) {
					String areaUsu = u.getTbArea().getDescripcion().trim();
					String nomComp = u.getNombres().trim() + " "
							+ u.getApellPater().trim() + " "
							+ u.getApellMater().trim();
					if (compararCadenas(areaUsu, query.trim()) == true
							|| compararCadenas(nomComp, query.trim())) {
						String desc = areaUsu + " - " + nomComp;
						results.add(desc);
					}
				}
			}
			if (results.size() < 1) {
				results.add("No se encuentran resultados");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

		return results;

	}

	private List<DocumentoInternoDTO> listDocInt;
	private DocumentoInternoDTO docSelected;

	public DocumentoInternoDTO getDocSelected() {
		return docSelected;
	}

	public void setDocSelected(DocumentoInternoDTO docSelected) {
		this.docSelected = docSelected;
	}

	public List<DocumentoInternoDTO> getListDocInt() {
		listDocInt = ListaGeneral.getListDocumentoInternosUsuario();
		return listDocInt;
	}

	public void setListDocInt(List<DocumentoInternoDTO> listDocInt) {
		this.listDocInt = listDocInt;
	}

	private boolean compararCadenas(String fijo, String prmt) {
		int eval = (fijo.toUpperCase()).indexOf((prmt).toUpperCase());

		if (eval == -1) {
			return false;
		} else {
			return true;
		}
	}

	private List<DocumentoInternoDTO> listaDocumentosInternosUsuario(
			Usuario UserLog) {
		List<DocumentoInternoDTO> doc = serDocInt
				.listaDocumentoInternoUsuario(UserLog);
		return doc;

	}

	// //////////////////////////////////////////////////////////////////////////////////////
	public void accionFileUpload(FileUploadEvent e) {

		/*
		 * String nomdoc = e.getFile().getFileName(); StringTokenizer st = new
		 * StringTokenizer(nomdoc, "."); String ext = st.nextToken(); ext =
		 * st.nextToken();
		 * 
		 * byte[] losbytes = e.getFile().getContents(); Blob blob =
		 * Hibernate.createBlob(losbytes);
		 * 
		 * String pathname = "C:\\word\\doc." + ext; // System.out.println("@@@"
		 * + nomdoc + "@@@"); File file = new File(pathname);
		 * 
		 * POITextExtractor extractor = null; try { FileOutputStream fos = new
		 * FileOutputStream(file); InputStream inStream =
		 * blob.getBinaryStream(); int size = (int) blob.length(); byte[] buffer
		 * = new byte[size]; int length = -1; while ((length =
		 * inStream.read(buffer)) != -1) { fos.write(buffer, 0, length); }
		 * 
		 * fos.close(); inStream.close(); File inputFile = new File(pathname);
		 * 
		 * extractor = ExtractorFactory.createExtractor(inputFile); value =
		 * extractor.getText(); inputFile.delete();
		 * 
		 * } catch (Exception e1) { e1.printStackTrace(); } //
		 * http://piotr-plonka
		 * .blogspot.com/2011/04/microsoft-office-text-extraction-in.html
		 */}

	// otra solucion jejeje
	private List<RequisitoProcesosDTO> listaArchivo;

	// private static int contador = 1;
	public void subirDocumentoAuxiliares(FileUploadEvent e) {
		try {
			RequisitoProcesosDTO archivo = null;
			System.out.println(listaArchivo.size());
			if (listaArchivo.size() < 5) {
				archivo = new RequisitoProcesosDTO();
				archivo.setNombreArchivo(e.getFile().getFileName());
				archivo.setInputStream(e.getFile().getInputstream());
				listaArchivo.add(archivo);
				docInter.setListBytes(listaArchivo);
			}
		} catch (Exception e2) {
			e2.printStackTrace();
		}
	}

	// aca esta para enviar documentos anxados en el expediente

	public List<RequisitoProcesosDTO> getListaArchivo() {
		return listaArchivo;
	}

	public void setListaArchivo(List<RequisitoProcesosDTO> listaArchivo) {
		this.listaArchivo = listaArchivo;
	}

	public DocumentoInternoDTO getDocInter() {
		return docInter;
	}

	public void setDocInter(DocumentoInternoDTO docInter) {
		this.docInter = docInter;
	}

	private BandejaDTO objBandeja;

	public String crearDocumentoInterno() {
		try {
			objBandeja = new BandejaDTO();
			objBandeja = loginBM.getObjBandeja();
			docInter = new DocumentoInternoDTO();
			
			
			// Para saber que tipo de documentos son... y ver si le damos la
			// opcion a elegir
			// por el tipo de accion que se le ha dado
			setEstadoCombo(false);

			return "crearInformeResolucion";
		} catch (NullPointerException e) {
			Util.mensaje("Debe seleccionar un expediente", "");
			return "expedientes";
		} catch (Exception e) {
			e.printStackTrace();
			return "expedientes";
		}
	}

	private boolean estadoCombo;

	public boolean isEstadoCombo() {
		return estadoCombo;
	}

	public void setEstadoCombo(boolean estadoCombo) {
		this.estadoCombo = estadoCombo;
	}

	// /////////////*********************************
	public String adjuntarDocumento() {
		String link = "";
		String mensaje = "";
		try {
			if (this.idComboTipDocInt == -1) {
				mensaje = "Seleccione un tipo de documento";
				link = "crearDocumento";
			} else {
				docInter.setId_documento(this.idComboTipDocInt);
				docInter.setIdExpediente(objBandeja.getIdentity());
				
				System.out.println("El id de documento es: ..."
						+ objBandeja.getIdentity());
				System.out.println("El id de documento es: ..."
						+ objBandeja.getIdExpediente());
				if (objBandeja.getIdTipoAccion() == 10
						|| objBandeja.getIdTipoAccion() == 11
						|| objBandeja.getIdTipoAccion() == 12) {
					link = "evaluarExpediente";
				} else {
					link = "expedientes";
				}
				Accion accion = new Accion();
				accion.setIdAccion(objBandeja.getIdTipoAccion());
				mensaje = serDocInt.registrarDocumentoInterno(objBandeja,
						docInter, loginBM.getObjUsuarioAux(), accion);

				limpiar();
			}

			Util.mensaje(mensaje, "");
		} catch (Exception e) {
			link = "crearDocumento";
			e.printStackTrace();
		}
		return link;
	}

	public String crearInformeResolucion() {
		try {
			setLstDocumentosInternos(new ArrayList<TipoDocumentosInternos>());
			setLstDocumentosInternos(serDocInt.listarDocumentosInternos());
			objBandeja = new BandejaDTO();
			objBandeja = loginBM.getObjBandeja();
			docInter = new DocumentoInternoDTO();
			listaArchivo = new ArrayList<RequisitoProcesosDTO>();
			// Para saber que tipo de documentos son... y ver si le damos la
			// opcion a elegir
			// por el tipo de accion que se le ha dado
			// Para saber que tipo de documento es ^^^
			if (objBandeja.getIdTipoAccion() == 10
					|| objBandeja.getIdTipoAccion() == 12) {
				setIdComboTipDocInt(1);
				docInter.setIdTipoDocumento(1);
			}
			if (objBandeja.getIdTipoAccion() == 11) {
				setIdComboTipDocInt(2);
				docInter.setIdTipoDocumento(2);
			}
			setEstadoCombo(true);
			docInter.setCodigo(serDocInt.obtenerCodigoTipoDocumento(docInter));
			docInter.setUsuario_remitente(getUserLog().getNombres() + " "
					+ getUserLog().getApellPater() + " "
					+ getUserLog().getApellMater());
			docInter.setFechaRegistro(Validaciones.getTimeStampFromServer());
			setIdComboTipDocInt(1);
			return "crearInformeResolucion";
		} catch (NullPointerException e) {
			e.printStackTrace();
			Util.mensaje("Debe seleccionar un expediente", "");
			return "expedientes";
		} catch (Exception e) {
			e.printStackTrace();
			return "expedientes";
		}		
	}

	public void vistaPreviaInformeResolucion(ActionEvent a) {
		docInter.setUsuario_remitente(loginBM.getObjUsuarioAux()
				.getApellPater()
				+ " "
				+ loginBM.getObjUsuarioAux().getApellMater()
				+ ", "
				+ loginBM.getObjUsuarioAux().getNombres());
		for (TipoDocumentosInternos d : lstDocumentosInternos) {
			if (d.getIdTipoDocumentoInternos() == this.idComboTipDocInt) {
				docInter.setNombreTipoDocumento(d.getDescripcion());
				break;
			}
		}
		docInter.setFecha_registro(Validaciones.ConvertirFechaToString(null,
				Validaciones.getDateFromServer()));
	}

	@ManagedProperty(value = "#{loginBM}")
	private LoginBM loginBM;

	public LoginBM getLoginBM() {
		return loginBM;
	}

	public void setLoginBM(LoginBM loginBM) {
		this.loginBM = loginBM;
	}

	// //////////////////////////////
	public String irDocumentosCreados() {
		setLstUsuariosCopia(new ArrayList<Usuario>());
		setLstUsuariosDistino(new ArrayList<Usuario>());
		setLstDocumentoCreadosUsuario(new ArrayList<DocumentoInternoDTO>());
		setLstDocumentoCreadosUsuario(serDocInt.listaDocumentosUsuarioCreados(loginBM.getObjUsuarioAux()));
		return "documentosCreados";
	}

	public String irCrearDocumento() {
		setLstDocumentosInternos(new ArrayList<TipoDocumentosInternos>());
		setLstDocumentosInternos(serDocInt.listarDocumentosInternos());

		setIdComboTipDocInt(-1);
		setDocInter(new DocumentoInternoDTO());
		listUsers = serDocInt.listarTodosUsuarios();
		setListaArchivo(new ArrayList<RequisitoProcesosDTO>());
		docInter.setCodigo("");
		docInter.setNombreTipoDocumento("");
		docInter.setFechaRegistro(Validaciones.getTimeStampFromServer());
		setLstUsuariosCopia(new ArrayList<Usuario>());
		setLstUsuariosDistino(new ArrayList<Usuario>());
		return "crearDocumento";
	}

	private List<Usuario> lstUsuariosDistino;
	private List<Usuario> lstUsuariosCopia;

	public List<Usuario> getLstUsuariosDistino() {
		return lstUsuariosDistino;
	}

	public void setLstUsuariosDistino(List<Usuario> lstUsuariosDistino) {
		this.lstUsuariosDistino = lstUsuariosDistino;
	}

	public List<Usuario> getLstUsuariosCopia() {
		return lstUsuariosCopia;
	}

	public void setLstUsuariosCopia(List<Usuario> lstUsuariosCopia) {
		this.lstUsuariosCopia = lstUsuariosCopia;
	}

	public void agregarUsuarioDestino(ActionEvent a) {
		try {
			Usuario u = obtenerUsuarioDestino(getUsuDes());
			setUsuDes("");
			if (u == null) {
				Util.mensajeCompletoAdvertencia("Advertencia",
						"El usuario no existe, vuelva a seleccionar");
				return;
			}
			for (Usuario ud : lstUsuariosDistino) {
				if (ud.getIdUsuario() == u.getIdUsuario()) {
					Util.mensajeCompletoAdvertencia("Advertencia",
							"Usted ya se registro .... lista destino");
					return;
				}
			}
			lstUsuariosDistino.add(u);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void agregarUsuarioCopia(ActionEvent a) {
		try {
			Usuario u = obtenerUsuarioDestino(getUsuCop());
			setUsuCop("");
			if (u == null) {
				Util.mensajeCompletoAdvertencia("Advertencia",
						"El usuario no existe, vuelva a seleccionar");
				return;
			}
			for (Usuario ud : lstUsuariosCopia) {
				if (ud.getIdUsuario() == u.getIdUsuario()) {
					System.out.println("LLEGO ACA UNA VEZ ");
					Util.mensajeCompletoAdvertencia("Advertencia",
							"Usted ya se registro .... lista copia");
					return;
				}
			}
			lstUsuariosCopia.add(u);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String usuDes;
	private String usuCop;

	public String getUsuCop() {
		return usuCop;
	}

	public void setUsuCop(String usuCop) {
		this.usuCop = usuCop;
	}

	public String getUsuDes() {
		return usuDes;
	}

	public void setUsuDes(String usuDes) {
		this.usuDes = usuDes;
	}

	private Usuario obtenerUsuarioDestino(String parametro) {
		Usuario abc = null;
		try {
			String nomb = "";
			StringTokenizer st;
			st = new StringTokenizer(parametro, "-");
			while (st.hasMoreElements()) {
				nomb = ((String) st.nextElement()).trim();
			}
			String nombUserLog = "";
			for (Usuario u : listUsers) {
				nombUserLog = u.getNombres().trim() + " "
						+ u.getApellPater().trim() + " "
						+ u.getApellMater().trim();
				if (nombUserLog.equals(nomb)) {
					abc = u;
					break;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return abc;
	}

	private DocumentoInternoDTO docInter;

	private List<TipoDocumentosInternos> lstDocumentosInternos;

	public List<TipoDocumentosInternos> getLstDocumentosInternos() {
		return lstDocumentosInternos;
	}

	public void setLstDocumentosInternos(
			List<TipoDocumentosInternos> lstDocumentosInternos) {
		this.lstDocumentosInternos = lstDocumentosInternos;
	}
	
	public void vistaPreviaDocumentoInterno(ActionEvent a) {
		String usuDestino = "";
		if(lstUsuariosDistino.size()<1){
			usuDestino = "----";
		}
		else{
			for (Usuario u : lstUsuariosDistino) {
				usuDestino+=( u.getApellPater() + " "
							+ u.getApellMater() + ", "
							+ u.getNombres()+"; ");
			}
		}
		
		
		docInter.setContenido(this.value);
		docInter.setUsuario_remitente(loginBM.getObjUsuarioAux()
				.getUsuarioNombreCompleto());
		docInter.setUsuario_destino(usuDestino);
		for (TipoDocumentosInternos d : lstDocumentosInternos) {
			if (d.getIdTipoDocumentoInternos() == this.idComboTipDocInt) {
				docInter.setNombreTipoDocumento(d.getDescripcion());
				break;
			}
		}
		docInter.setFecha_registro(Validaciones.ConvertirFechaToString(null,
				Validaciones.getDateFromServer()));
	}
	
	//Esta son los documentos creados por el usuario
	private List<DocumentoInternoDTO> lstDocumentoCreadosUsuario;

	public List<DocumentoInternoDTO> getLstDocumentoCreadosUsuario() {
		return lstDocumentoCreadosUsuario;
	}

	public void setLstDocumentoCreadosUsuario(
			List<DocumentoInternoDTO> lstDocumentoCreadosUsuario) {
		this.lstDocumentoCreadosUsuario = lstDocumentoCreadosUsuario;
	}
	
	public void actionSeleccionarDocumento(SelectEvent s) {
		setDocSelected((DocumentoInternoDTO) s.getObject());
	}

}
